package server.business.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.web.bind.annotation.*;
import server.business.pojo.BloodInformation;
import server.business.service.*;
import server.business.vo.Result;
import server.business.vo.ResultExpand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ccb
 * @date 2022/09/02
 */
@Controller
@RequestMapping("/bloodInformation")
public class BloodInformationController {
    
    @Autowired
    private BloodInformationService bloodInformationService;

    @Resource
    private StateService stateService;
    @Resource
    private PatientTransfusionInformationService patientTransfusionInformationService;
    @Resource
    private BloodStockService bloodStockService;
    @Resource
    private BloodOutboundService bloodOutboundService;
    @Resource
    private BloodCompositionService bloodCompositionService;

    @Resource
    private AboTypeService aboTypeService;
    @Resource
    private RhTypeService rhTypeService;
    @Resource
    private DepartmentService departmentService;
//    @RequestMapping("/bloodInformation")
//    public String toBloodInformation(){
//        return "pages/bloodInformation";
//    }

    /**
     * 更改血液信息
     * @param bloodInformation
     */
    @RequestMapping(value = "/normal/updateBloodInfo", method = RequestMethod.PUT)
    @ResponseBody
    public server.business.utils.results.lrz.Result updateBloodInfo(@RequestBody BloodInformation bloodInformation){
        bloodInformationService.updateBloodInfo(bloodInformation);
        server.business.utils.results.lrz.Result result = new server.business.utils.results.lrz.Result();
        result.setCode("200");
        result.setMsg("血液信息更改成功");
        return result;
    }
    
    @RequestMapping("/normal/query")
    @ResponseBody
    public List<BloodInformation> queryData(){
        List<BloodInformation> list = bloodInformationService.queryData();
        return list;
    }
    
    @RequestMapping("/normal/listByPage")
    @ResponseBody
    public ResultExpand getPage(HttpServletRequest request, HttpServletResponse response){
        ResultExpand resultExpand = new ResultExpand();
        resultExpand = bloodInformationService.getPage(request, response);
        return resultExpand;
    }

    /**
     * 搜索血液信息
     *
     * @param request  请求
     * @param response 响应
     * @return {@link ResultExpand}
     */
    @RequestMapping("/normal/searchBloodInformation")
    @ResponseBody
    public ResultExpand searchBloodInformation(HttpServletRequest request, HttpServletResponse response) {
        ResultExpand resultExpand = new ResultExpand();
//        resultExpand = bloodInformationService.searchBloodInformation(request, response);
        resultExpand = bloodInformationService.searchBloodInformation(request, response);
        return resultExpand;
    }
    
    @RequestMapping("/normal/outboundBlood")
    @ResponseBody
    public Result outboundBlood (HttpServletRequest request, HttpServletResponse response) {
        Result result = new Result();
        result = bloodInformationService.outboundBlood(request,response);
        return result;
    }

    /**
     * 下载excel
     *
     * @param request  请求
     * @param response 响应
     */
    @RequestMapping("/normal/downloadExcel")
    public void downloadExcel(HttpServletRequest request, HttpServletResponse response){
       bloodInformationService.downloadExcel(request, response);
    }







    //**********fzx*******************************************************************************
    //********************************************************************************************

    /**
     *科室字典
     * @return listDepartment
     * @dictionary  Department
     */
    @GetMapping("/normal/listDepartment")
    @ResponseBody
    public server.business.utils.results.fzx.Result listDepartment() {
        return server.business.utils.results.fzx.Result.success(departmentService.list());
    }

    @GetMapping("/normal/getPersonBloodInfo")
    @ResponseBody
    public server.business.utils.results.fzx.Result getPersonBloodInfo(@RequestParam(value = "patientId")String patientId,
                                                                       @RequestParam(value = "startTime")  String startTimePatient,
                                                                       @RequestParam(value = "endTime") String endTimePatient) {
        Timestamp startTime = Timestamp.valueOf(startTimePatient);
        Timestamp endTime = Timestamp.valueOf(endTimePatient);
        return server.business.utils.results.fzx.Result.success(patientTransfusionInformationService.getPersonBloodInfo(patientId,startTime,endTime));
    }
    /**
     * 科室用血统计
     *
     * @return BloodRecored
     * @dictionary AboBloodType RhBloodType
     */

    @GetMapping("/normal/getDepartBloodInfo")
    @ResponseBody
    public server.business.utils.results.fzx.Result getDepartBloodInfo(@RequestParam(value = "department")String department,
                                                                       @RequestParam(value = "startTime")  String startTimeDepart,
                                                                       @RequestParam(value = "endTime") String endTimeDepart) {
        Timestamp startTime = Timestamp.valueOf(startTimeDepart);
        Timestamp endTime = Timestamp.valueOf(endTimeDepart);
        return server.business.utils.results.fzx.Result.success(patientTransfusionInformationService.getDepartBloodInfo(department,startTime,endTime));
    }
    /**
     * 统计各种血液流通情况
     *
     * @return
     */
    @GetMapping("/normal/getBloodFlowReport")
    @ResponseBody
    public server.business.utils.results.fzx.Result getBloodFlowReport(@RequestParam(value = "startTime")  String startTimeDepart,
                                                                       @RequestParam(value = "endTime") String endTimeDepart) {
        Timestamp startTime = Timestamp.valueOf(startTimeDepart);
        Timestamp endTime = Timestamp.valueOf(endTimeDepart);

        List<Map<String, Object>> sourceList = bloodStockService.getBloodInReport(startTime,endTime);

        List<Map<String, Object>> newList =  bloodStockService.getBloodFailReport(startTime,endTime);

        // ================ 利用Java8的Stream流实现合并 =========================
        sourceList.addAll(bloodStockService.getBloodFailReport(startTime,endTime));
        sourceList.addAll(bloodStockService.getBloodOutReport(bloodOutboundService.getBloodOutReportList(startTime,endTime)));
        List<Map<String,Object>> combine = sourceList.stream()
//        Map<Object, List<Student>> newList = studentList.stream().collect(Collectors.groupingBy(student -> student.getName() + ":" + student.getSex()+ ":" + student.getAge()))
                .collect(Collectors.groupingBy(BloodStock -> BloodStock.get("blood_variety").toString()+":"+ BloodStock.get("rh_blood_type").toString()+":"+ BloodStock.get("abo_blood_type"))) // 根据map中id的value值进行分组, 这一步的返回结果Map<String,List<Map<String, Object>>>，目的是将相同id下的value归类到一个value下
                .entrySet() // 得到Set<Map.Entry<String, List<Map<String, Object>>>
                .stream() // 使用Java8的流
                .map(m -> { // 进入映射环境
                    // m.getValue()的结果是 List<Map<String, Object>>
                    Map<String, Object> collect = m.getValue().stream()
                            // 核心重点！o.entrySet() 的结果是 Set<Map.Entry<String, Object>>，通过flatMap将value合并成一个stream
                            .flatMap(o -> o.entrySet().stream())
                            // (m1, m2) -> m2 的意思是如果 m1 == m2 则使用m2
                            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (m1, m2) -> m2));
                    return collect;
                }).collect(Collectors.toList());
        System.out.println("final:"+combine);
        for (int i = 0; i < combine.size(); i++) {
            Map<String,Object> obj = combine.get(i);
            if(!obj.containsKey("InHp")){
                combine.get(i).put("InHp",0);
            }
            if(!obj.containsKey("OutHp")){
                combine.get(i).put("OutHp",0);
            }
            if(!obj.containsKey("FailHp")){
                combine.get(i).put("FailHp",0);
            }
            Double increase = Double.valueOf(String.valueOf(combine.get(i).get("InHp")))
                    -Double.valueOf(String.valueOf(combine.get(i).get("OutHp"))) -Double.valueOf(String.valueOf(obj.get("FailHp")));
            combine.get(i).put("cleanIncrease",increase);
        }
        return server.business.utils.results.fzx.Result.success(combine);
    }
    @GetMapping("/normal/getBloodState")
    @ResponseBody
    public server.business.utils.results.fzx.Result getState(@RequestParam(value = "state") String state) {
        String  getResult=stateService.getState(state);
        return server.business.utils.results.fzx.Result.success(getResult);
    }
    /**
     * 追踪某批次血液去向
     *
     * @return
     */
    @GetMapping("/normal/getBloodGo")
    @ResponseBody
    public server.business.utils.results.fzx.Result getBloodGo(@RequestParam(value = "bloodId") String bloodId) {
        HashMap<String, Object> getResult=new HashMap<>();
        getResult= bloodInformationService.getFrom(bloodId);
        if(getResult==null){
            return server.business.utils.results.fzx.Result.fail();
        }
        //ABO字典
        Object getAbo = getResult.get("abo_blood_type");
        if(getAbo instanceof String){  //判断键值是否为String类型
            String value = (String)getAbo;
            String abo = aboTypeService.getAbo((value));
            getResult.put("abo_blood_type",abo);
        };
        //rh字典
        Object getRh = getResult.get("rh_blood_type");
        if(getRh instanceof String){  //判断键值是否为String类型
            String value = (String)getRh;
            String rh = rhTypeService.getRh((value));
            getResult.put("rh_blood_type",rh);
        };
        //composition字典
        Object getComposition = getResult.get("blood_component");
        if(getComposition instanceof String){  //判断键值是否为String类型
            String value = (String)getComposition;
            String composition = bloodCompositionService.getComposition(value);
            getResult.put("blood_component",composition);
        };
        System.out.println(getResult);

        //State字典
        Object getState = getResult.get("state");
        if(getState instanceof String){  //判断键值是否为String类型
            String value = (String)getState;

            String composition = stateService.getState(value);
            getResult.put("newstate",composition);

        };
        System.out.println(getResult);

//        List myList = new ArrayList();
//        myList.add(getResult);
        return server.business.utils.results.fzx.Result.success(getResult);

    }
    //**********fzx***************************end



    // *************************************lrz*************************start
    @GetMapping("/normal/getAll")
    @ResponseBody
    public server.business.utils.results.lrz.Result getAll() {
        List<BloodInformation> bloodInformations = bloodInformationService.getAll();
        return server.business.utils.results.lrz.Result.success(bloodInformations);
    }

    /**
     * 分页查询
     *
     * @param currentPage
     * @param pageSize
     * @param bloodInformation
     * @return
     */
    @GetMapping("/normal/{currentPage}/{pageSize}")
    @ResponseBody
    public server.business.utils.results.lrz.Result getPage(@PathVariable int currentPage, @PathVariable int pageSize,
                                                            BloodInformation bloodInformation) {
        IPage<BloodInformation> page = bloodInformationService.getPage(currentPage, pageSize, bloodInformation);
        // 如果当前页码值大于了总页码值，就重新执行查询操作，使用最大页码值作为当前页码值
        if (currentPage > page.getPages()) {
            page = bloodInformationService.getPage((int) page.getPages(), pageSize, bloodInformation);
        }
        return server.business.utils.results.lrz.Result.success(page);
    }

    /**
     * 更改基本血液表状态
     *
     * @param bloodInformation
     * @return
     */
    @RequestMapping(value = "/normal/setBloodInfoState", method = RequestMethod.PUT)
    @ResponseBody
    public server.business.utils.results.lrz.Result setBloodState(@RequestBody BloodInformation bloodInformation) {
        // 更改血液基本信息表中的血液状态
        bloodInformationService.setStateByBloodId(bloodInformation.getBloodId(), bloodInformation.getState());
        return server.business.utils.results.lrz.Result.success("基本血液信息表状态更改完毕");
    }

    /**
     * 获得血液信息
     *
     * @param bloodInformation
     * @return
     */
    @GetMapping(value = "/normal/getBloodInfo")
    @ResponseBody
    public server.business.utils.results.lrz.Result getBloodInStockByTransfusion(BloodInformation bloodInformation) {
        // 首先根据血型找到符合条件的血液
        BloodInformation data = bloodInformationService
                .getSingleBloodInStockByTransfusion(bloodInformation);
        // 返回符合条件的血液信息
        server.business.utils.results.lrz.Result result = new server.business.utils.results.lrz.Result();
        if (data == null) {
            result.setMsg("未找到匹配的血液信息");
            result.setCode("500");
            return result;
        }
        return server.business.utils.results.lrz.Result.success(data);
    }

    /**
     * 根据血液编号获取血液信息
     *
     * @param bloodInformation
     * @return
     */
    @GetMapping(value = "/normal/getBloodInfoByBloodId")
    @ResponseBody
    public server.business.utils.results.lrz.Result getBloodInfo(BloodInformation bloodInformation) {
        return server.business.utils.results.lrz.Result.success(bloodInformationService.getBloodInfo(bloodInformation));
    }
    // *************************************lrz*************************end





}
